package com.ljy.my_study.java.juc.forkjoinpool;

import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

public class SortTask extends RecursiveAction {

    public static void main(String[] args) throws InterruptedException {
//        long[] array=new long[]{12,13,2,25,76,12,13,16,56,34,86,94,23,21};
        int len=100000;
        long[] origin=new long[len];
        for(int i=0;i<len;i++){
            origin[i]=(int)(Math.random()*100);
        }

        long[] array=new long[len];
        System.arraycopy(origin,0,array,0,len);

        SortTask sortTask=new SortTask(array);
        ForkJoinPool forkJoinPool=new ForkJoinPool();
        long start=System.currentTimeMillis();
        forkJoinPool.submit(sortTask);
        System.out.println(System.currentTimeMillis()-start);
        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(10, TimeUnit.SECONDS);
//        System.out.println(Arrays.toString(array));

        System.arraycopy(origin,0,array,0,len);
        start=System.currentTimeMillis();
        Arrays.sort(array);
        System.out.println(System.currentTimeMillis()-start);
    }

    private long[] array;

    private int lo;

    private int hi;

    public SortTask(long[] array){
        this.array=array;
        this.lo=0;
        this.hi=array.length-1;
    }

    public SortTask(long[] array,int lo,int hi){
        this.array=array;
        this.lo=lo;
        this.hi=hi;
    }

    @Override
    protected void compute() {
        if(lo<hi){
//            System.out.println(Thread.currentThread().getName()+" start.");
            int p=partition(array,lo,hi);
            SortTask left=new SortTask(array,lo,p-1);
            SortTask right=new SortTask(array,p+1,hi);
            left.fork();
            right.fork();
//            try {
//                Thread.sleep(1000L);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            left.join();
//            System.out.println(Thread.currentThread().getName()+",left join end.");
            right.join();
//            System.out.println(Thread.currentThread().getName()+",right join end.");
        }
    }

    private int partition(long[] array,int lo,int hi){
        long x=array[hi];
        int j=lo-1;
        for(int i=lo;i<hi;i++){
            if(array[i]<=x){
                j++;
                swap(array,i,j);
            }
        }
        swap(array,j+1,hi);
//        try {
//            Thread.sleep(1000L);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return j+1;
    }

    private void swap(long[] array,int i,int j){
        if(i!=j){
            long temp=array[i];
            array[i]=array[j];
            array[j]=temp;
        }
    }
}
